┌────────────────┐ ┌───────────────┐ ┌───────────────┐ ┌────────────────┐ │ ┌─────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │ │ ┌────┐ ┌─────┐ │ │ └───┐ │ │ ┌──┘ │ │ └──┐ │ │ ┌──┘ │ │ └──┐ │ │ ┌──┘ │ │ └──┐ │ │ ┌─┐ │ │ └─────┘ │ │ └────┘ └────┘ │ │ └────┘ └────┘ │ │ └────┘ └────┘ │ │ │ └─┘ │ ┌───────┘ └───────────────┘ └───────────────┘ └───────────────┘ │ └─────┘ │ ┌─────┐ │ ┌─────┐ │ │ ┌─┐ │ THE │ │ ┌─┐ │ │ └─┘ │ │ │ └─┘ │ │ └─────┘ │ パブリック ドメイン マニュアル └─────┘ │ ┌─────┐ │ ┌─────┐ │ │ ┌─┐ │ │ of │ ┌─┐ │ │ │ │ └─┘ │ │ │ └─┘ │ │ └─────┘ エンハンスト グラフィック チャーシュー │ └─────┘ │ ┌─────┐ │ ┌─────┐ │ │ ┌─┐ │ │ │ ┌─┐ │ │ └─┘ │ │ (Ver. 0.55) │ └─┘ │ │ └─────┘ │ └─────┘ │ ┌─────┐ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌───────┘ │ ┌─┐ │ │ │ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │ │ ┌────┐ ┌────┐ │ │ ┌─────┐ │ │ └─┘ │ │ └──┐ │ │ ┌──┘ │ │ └──┐ │ │ ┌──┘ │ │ └──┐ │ │ ┌──┘ │ │ └───┐ │ │ └─────┘ └────┘ │ │ └────┘ └────┘ │ │ └────┘ └────┘ │ │ └────┘ └─────┘ │ └────────────────┘ └───────────────┘ └───────────────┘ └────────────────┘ Written by Applause はじめに 98シリーズは、広く普及している割りには、EGCをはじめとして完璧なマニュアルがなかなか手に入りません。手に入っても間違いが多く、たくさんの人がどうして思いどおりに動かないのかとさんざん悩んだあげく、マシン語への情熱さえも削がれて悲しい思いをしたことだろうと思います。大体、日本のマニュアルときたら不親切で読みにくく間違いだらけなものばかりです。そこで、今まで挫折していた人やこれから挑戦しようという人が、ハードウェアの解析を自分でしなおすなんてことをしなくてもいいように、このEGCマニュアルを発表したいと思います。 他人の作ったルーチンを取り込んで使いこなしていくのも一つの芸術ですが、マシン語をつかって自分の手でハードウェアをコントロールするのも楽しいものです。ぜひ多くの人にそういう楽しみも知ってもらいたいと思います。 EGCの、4プレーン同時転送、4プレーン同時演算、ドット単位のシフト、などの機能を使えばボックスコピールーチンや高速なペイントルーチン、VRAMの半分をスプライト領域として高速な擬似スプライトなどが実現できるでしょう。 プログラマーの皆さん是非ともこのマニュアルをもとにEGCを極限まで生かしたPDSを作って多くの98所有者を楽しませて下さい。 なお、本マニュアルも正式なものではありませんので、間違いがあると思われます。気づかれた方は是非ご連絡ください。また、「できるだけ読みやすいものを」という志に必ずしもそうものとなっていないかもしれません。今の所は、ご容赦ください。 ╌╌╌╌╌╌╌╌╌╌╌ § § § EGCの有効化 § § § ╌╌╌╌╌╌╌╌╌╌╌╌ EGCとは、エンハンストグラフィックチャージャーの略であることからも解るように、GRCG(グラフィックチャージャー)の機能を拡張したものです。したがって、EGCを有効化するには、まずGRCGを有効化し、次にEGCモードに切り替えるという手順を踏みます。実際には、次のようにします。 EGC_ONPROC MOVAL,80H;GRCGの有効化。 80Hは、C0Hでもよい。 OUT7CH,AL; MOVAL,7;フリップフロップを変更可能へ OUT6AH,AL; MOVAL,5;EGCモードへ OUT6AH,AL; MOVAL,6;フリップフロップを変更不能へ OUT6AH,AL; END SUB ここで最後のフリップフロップの変更を不可能にするという手順はしなくても問題ないはずですが、たぶん誤ってI/Oポート6AHに書き込みを行うプログラムがあった場合、異常の原因を解明するのが難くなるという理由で、こうすることになっているのでしょう。 また、ウエイトは、入れなくても9821Apでも動いているので問題ないでしょう。MATEには、MATE用のEGCが入っているのだったら何の根拠にもなりませんが。 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ § § § EGCのレジスタ群 § § § ╌╌╌╌╌╌╌╌╌╌╌╌╌╌ EGCには16ビットのレジスタが全部で8本あり、これらにOUT DX,AX 命令で値を設定することでEGCの動作モードを指定します。 《プレーンマスクレジスタ,I/Oポート4A0H》 このレジスタは、EGCによる書き込みあるいは読み込みをプレーン毎に有効 にするか無効にするかを設定します。 このレジスタのビット0がプレーン0に、 ビット1がプレーン1に、 ビット2がプレーン2に、 ビット3がプレーン3に対応します。 これらのビットが 0ならば、書き込みによってビットの対応するプレーンの内容が書き換えられ、 1ならば、対応するプレーンの内容は、そのままです。即ち、そのプレーンは、 「マスクされた」と言います。 また、後述するコンペアリードもそれぞれのプレーンに対応する上記のビットが 0のプレーンに対して行われます。 ビット4からビット15までは、4,096色中16色表示のモードでは、未使 用なのですべて1にしておきます。 (実は、H98の16,777,216色中の256色表示モードでは、 ビット4からビット7がプレーン4からプレーン7に対応していることを、 実際に確認しています。 残念ながらPC9801GSの65,536色モードでEGCが有効なのか、 ビット8からビット15がプレーン8からプレーン15に対応するのかは、 判っていません。) 《モードレジスタ0,I/Oポート4A2H》 ・ このレジスタのビット0からビット7は未使用です。すべて1にします。 ・ ビット8からビット11で、ワンプレーンリードの時に読み込むプレーンを 4ビットの数値として設定します。即ち、 ビット 11 10 9 8 0 0 0 0 ならプレーン0を読み込む。 0 0 0 1 ならプレーン1を読み込む。 0 0 1 0 ならプレーン2を読み込む。 0 0 1 1 ならプレーン3を読み込む。 というふうになっています。 (H98の16,777,216色中の256色表示モードでこの4ビット に4〜7の値を設定するとプレーン4からプレーン7を指定することに なるのかは、不明です。判っていません。だれか調べて下さい。) ・ ビット12は未定義です。 常に0とします。 ・ ビット13とビット14で、ラスター演算の入力データの一つである“P”と して、何を入力するかを選択します。ビット13のみが1の時、バックグラウン ドカラーが選択されます。ビット14のみが1の時、フォアグラウンドカラーが 選択されます。ビット13とビット14がともに1の時、フォアグラウンドカラ ーとバックグラウンドカラーが選択されます。ビット13とビット14がともに 0の時、パターンレジスタが選択されます。 フォアグラウンドカラー、バックグラウンドカラーの詳細は後述します。 ビット 14 13 0 0 パターンレジスタ 0 1 バックグラウンドカラー 1 0 フォアグラウンドカラー 1 1 フォアグラウンドカラーとバックグラウンドカラー ・ ビット15は未定義です。常に0とします。 《モードレジスタ1,I/Oポート4A4H》 ・ このレジスタのビット0からビット7で、ラスター演算を定義します。 ラスター演算には、“S”“P”“D”の三つの入力があります。 “P”は、モードレジスタ0のビット13及び14で、 “S”は、このレジスタのビット10でそれぞれ設定され、 “D”は、VRAM上のデータです。 ラスター演算はこれらについて、プレーン毎、ドット毎に次に示す論理演算を し、結果をVRAMに書き込む機能です。 _ R=B7・S・D・P + B6・S・D・P + _ _ _ B5・S・D・P + B4・S・D・P + _ _ _ B3・S・D・P + B2・S・D・P + _ _ _ _ _ B1・S・D・P + B0・S・D・P _ …… NOT、 + …… OR、 ・ …… AND、 B0〜B7は、このレジスタのビット0からビット7のこと。 RがVRAMに書き込むデータ。 ただし、Pとして フォアグラウンドカラーとバックグラウンドカラー が選択 されている場合は、次のようになります。 R=B7・S・D・F + B6・S・D・F + _ _ _ B5・S・D・F + B4・S・D・F + _ _ _ B3・S・D・B + B2・S・D・B + _ _ _ _ _ B1・S・D・B + B0・S・D・B Fはフォアグラウンドカラー、Bはバックグラウンドカラー。 ・ ビット8、9は、パターンレジスタの変更に関する設定です。 ビット 9 8 0 0 パターンレジスタを変更しない。 0 1 VRAMリード時にVRAMのデータをロード 1 0 VRAMライト時にライトする前のVRAMのデータを ロード。ただし、このレジスタのビット11、12で、 VRAMに書き込むデータとして“P”を選択し、モー ドレジスタ0のビット13、14で“P”として、パタ ーンレジスタを指定し、さらに、このレジスタのビット 13を1にした場合、VRAMにライトアクセスしても、 VRAMからパターンレジスタに読み込んだデータをそ のままVRAMに書き込むことになるので全く意味があ りません。 ただし、パターンレジスタへのデータのロードは、このレジスタのビット 13によって動作が異なります。即ち、ビット13が0ならば、モードレジ スタ0のビット8からビット11に設定された1プレーンの分のパターンレ ジスタだけを変更します。ビット13が1ならば、すべてのプレーンの分の パターンレジスタにそれぞれのプレーンのデータをロードします。 ・ ビット10は、ラスター演算の“S”を選択します。このビットが1ならば、 “S”には、CPUがVRAMに書き込んだデータが使われます。つまり、ラス ター演算は、CPUがVRAMにデータを書き込んだときのアドレスを受け取っ て処理をするのですが、このビットが1の場合、書き込んだデータも“S”とし てラスター演算に使われるのです。このビットが0の場合は、CPUがVRAM から読み込みを行ったときに、CPUがアクセスしたアドレスのVRAMのデー タを取り込み、これを“S”として、CPUがVRAMに書き込みを行った時に ラスター演算に使います。 今までに試したところによると、NECのEGCのうち古いものでは、このビ ットを1にした時は、このレジスタのビット13も1にしておかないとラスター 演算をしないようです。(VXで確認) 互換性のためには、この事に注意して 下さい。 また、このビットが1のときNECのEGCでは、ビット13のところで説明 する、ワンプレーンリード、コンペアリードが正常に働きません。 ・ ビット11とビット12は、VRAMに書き込むデータを選択します。 ビット11及びビット12がともに0の時、CPUのデータを4プレーンに書き 込みます。ビット11のみが1の時、それぞれのプレーン毎、ドット毎にラスタ ー演算をし、その結果を書き込みます。ビット12のみが1の時、モードレジス タ0のビット13とビット14で決まる“P”のデータをそのまま書き込みます。 いずれの場合もプレーンマスクレジスタでマスクされているプレーンは、ある いは、後述するドットマスクレジスタでマスクされているドットは、変更されま せん。また、同じく後述するシフトモードレジスタの設定によっても影響を受け ます。 ビット 12 11 0 0 CPUのデータ 0 1 ラスター演算の結果 1 0 パターンレジスタ ・ ビット13は、CPUがVRAMを読んだ時に読み出されるデータを選択しま す。ビット13が0ならCPUがVRAMから読み込みをした時にワンプレーン リードが行われモードレジスタ0のビット8からビット11で設定したプレーン のデータがそのまま読み込まれます。ビット13が1ならコンペアリードが行わ れます。コンペアリードとは、簡単に言うとVRAMのデータをドット毎に見た 時に後述のフォアグラウンドカラーと同じ色のドットは1として、そうでないド ットは0として読みだされるというものです。実際には、プレーンマスクレジス タで設定されたプレーンについてのみフォアグラウンドカラーとのコンペアが行 われるので必ずしも同じ色というわけではありません。 ただし、ワンプレーンリード、コンペアリードともに、このレジスタのビット 10が1の時は、正常に動作しません。 また、前述のようにこのビット13の設定によって、パターンレジスタの変更 の動作が変わります。 ・ ビット14、ビット15は未使用です。常に0にします。 《フォアグラウンドカラーレジスタ,I/Oポート4A6H》 ・ ビット0からビット3で、フォアグラウンドカラーを4ビットの数値として設 定します。モードレジスタ0のビット13あるいはビット14のどちらかが1に、 即ち“P”としてフォアグラウンドカラーかバックグラウンドカラーのどちらか が設定されていないと、変更できません。しかし、モードレジスタ0のビット1 3及びビット14をともに0にしても設定値は保存され、またコンペアリードの 時に使用できます。 ・ ビット4からビット15は、未使用です。常に0にします。 《ドットマスクレジスタ,I/Oポート4A8H》 このレジスタは、データを書き込む時のVRAMの内容が変更されるか保存さ れるかをドット毎に設定します。 プレーンマスクレジスタと逆でこのレジスタは、 ビットが0の時、対応するドットの色が保存され、 ビットが1の時、変更されます。 ビットとドットの対応は、VRAMにワードアクセス(もちろんEVENで) した時と同じです。つまり、 左から ビット7が 一番左のドット 1番目 ビット6が その右隣のドット 2番目 : : ビット0が 左から8番目のドット 8番目 ビット15が その右隣のドット 9番目 ビット14が その右隣のドット 10番目 : : ビット9が 右から2番目 15番目 ビット8が 一番右のドット 16番目 というふうに対応しています。 また、モードレジスタ0のビット13及びビット14がともに0に設定されて いないと変更できません。モードレジスタ0のビット13あるいはビット14の どちらかを1にしても設定は保存され、また有効です。 《バックグラウンドカラーレジスタ,I/Oポート4AAH》 ・ ビット0からビット3で、ラスター演算の“P”として使われるバックグラウ ンドカラーを4ビットの数値として設定します。またフォアグラウンドカラー同 様モードレジスタ0のビット13あるいはビット14のどちらかが1に、即ち “P”としてフォアグラウンドカラーかバックグラウンドカラーのどちらかが設 定されていないと、変更できません。しかし、モードレジスタ0のビット13及 びビット14をともに0にしても、設定値は保存されます。 ・ ビット4からビット15は未使用です。常に0にします。 《シフトモードレジスタ,I/Oポート4ACH》 ビット0からビット3でソースドットアドレスを、ビット4からビット7でデ ィスティネーションドットアドレスを、それぞれ4ビットの数値として設定しま す。ソースビットアドレス、ディスティネーションビットアドレスの詳細は、 § ラスター演算の実際(仮称、制作中)§ で説明したいと思っています。 ・ ビット12は、シフトディレクションを設定します。0なら右1なら左を意味 します。詳細は、§ ラスター演算の実際(仮称、制作中)§ で説明したいと思っ います。 ・ ビット8からビット11及びビット13からビット15は未使用です。常に0 にします。 《ドットレングスレジスタ,I/Oポート4AEH》 ビット0からビット11でドットレングスを設定します。一回の連続するアク セスで何ドットを変更(書き込み)するかを設定します。書き込みを行うドット 数−1を12ビットの数値として設定します。 シフトモードレジスタのビット 12(シフトディレクション)の設定によってドットの数え方が違います。詳細 は、§ ラスター演算の実際(仮称、制作中)§ で説明したいと思っています。 ・ ビット12からビット15は未使用です。常に0にします。 ╌╌╌╌╌╌╌╌╌╌╌ § § § EGC有効時のVRAMリード § § § ╌╌╌╌╌╌╌╌╌╌╌╌╌ EGCが有効な時には、VRAMに対するリードにワンプレーンリードとコンペアリードの2種類のモードがあり、モードレジスタ1のビット13に設定する値によって選択できます。もう一度書いておくと、このビットが0ならワンプレーンリード、1ならコンペアリードになります。 ワンプレーンリードについてはレジスタの説明のところの記述で分かると思いますのでここでは、コンペアリードについて具体例を挙げて説明しましょう。 まず、VRAMに次のようなデータが入っているとしましょう。 VRAMの内容(ドット毎) ドット 0 1 2 3 4 5 6 7 8 9 0AH 0BH 0CH 0DH 0EH 0FH 色 0 1 2 3 4 5 6 7 8 9 0AH 0BH 0CH 0DH 0EH 0FH ここで “ドット” の右に並んだ番号はドットのX座標を16で割った余りです。また、この例の16ドットのX座標を16で割った商は、すべて同じです。つまり何が言いたいかというと、この16ドットが、EVENのワードアクセスでまとめてリード、ライトできる16個の点であるということです。 同じデータをプレーン形式で示すと、 プレーン0 = 05555H プレーン1 = 03333H プレーン2 = 00F0FH プレーン3 = 0FF00H ※CPUがワードアクセスした時の形式で 書いているので、上位、下位が逆なのです。 そして、プレーンマスクレジスタとフォアグラウンドカラーを変えてVRAMの上記のデータが入っているアドレスにリードアクセスしてみると次の様にデータが読みだされます。 プレーンマスクレジスタ フォアグラウンドカラー リードされる値 (I/Oポート4A0H) (I/Oポート4A6Hの ビット0からビット3) 0FFF0H 0 0080H 〃 1 0040H 〃 2 0020H 〃 3 0010H 〃 4 0008H 〃 5 0004H 〃 6 0002H 〃 7 0001H 〃 8 8000H 〃 9 4000H 〃 A 2000H 〃 B 1000H 〃 C 0800H 〃 D 0400H 〃 E 0200H 〃 F 0100H 0FFF1H 0 00C0H 〃 1 00C0H 〃 2 0030H 〃 3 0030H 〃 4 000CH 〃 5 000CH 〃 6 0003H 〃 7 0003H 〃 8 C000H 〃 9 C000H 〃 A 3000H 〃 B 3000H 〃 C 0C00H 〃 D 0C00H 〃 E 0300H 〃 F 0300H 0FFF6H 0 00AAH 〃 1 0055H 〃 2 00AAH 〃 3 0055H 〃 4 00AAH 〃 5 0055H 〃 6 00AAH 〃 7 0055H 〃 8 AA00H 〃 9 5500H 〃 A AA00H 〃 B 5500H 〃 C AA00H 〃 D 5500H 〃 E AA00H 〃 F 5500H ╌╌╌╌╌╌╌╌╌╌╌ § § § EGCの無効化 § § § ╌╌╌╌╌╌╌╌╌╌╌╌ 無効化は、有効化の逆を行います。 EGC_OFFPROC MOVAL,7 OUT6AH,AL MOVAL,4 OUT6AH,AL MOVAL,6 OUT6AH,AL MOVAL,0 OUT7CH,AL EGC_OFFENDP これでEGCを無効化し普通の状態に戻すことができます。これ以外の手順は、必要ありません。 またいったん無効化して再び有効化してもそれぞれのEGCのレジスタの値は、保存されています。ただしGRCGを使うとEGCのレジスタで一部、値が変更されるものがあるます。 ╌╌╌╌╌╌╌╌╌╌╌╌ § § § EGCとGRCGの関係 § § § ╌╌╌╌╌╌╌╌╌╌╌╌ GRCGを使うとEGCのレジスタで変化するものがあると書きましたが、それらについて少し説明しておきましょう。 《マスクレジスタ》 GRCGをRMWモードで使ったとき、CPUがVRAMに書き込んだ値は、 マスクレジスタに書き込まれます。 例えばCPUがアドレスが偶数のバイトに3EHと書き込むとマスクレジスタ の値は、003EHになります。アドレスが奇数のバイトに87Hと書き込むと マスクレジスタの値は、8700Hになります。 またEVENのワードに 9B61Hと書き込むとマスクレジスタの値は、9B61Hになり、 ODDの ワードに530DHと書き込むと、0053Hとなります。 《フォアグラウンドカラーレジスタ》 フォアグラウンドカラーレジスタはEGCモードでは16色中の1色として設 定しますが、内部では、それを16ドット分のデータに拡張してフォアグラウン ドカラーレジスタに書き込んでいるものと考えて下さい。I/Oポート7EHを 通してGRCGのタイルレジスタに書き込みを行うと、書き込んだ8ドット分の データは、それを二つならべる形で16ドット分に拡張されフォアグラウンドカ ラーレジスタに書き込まれます。 例えば、I/Oポート4A6Hから000AHと書き込むと、フォアグラウン ドカラーレジスタの内部での値は、 データ0=0000H, データ1=FFFFH, データ2=0000H, ※ここでデータnとは、 データ3=FFFFH プレーンnに対応するデータのことです。 となります。そして、I/Oポート7CHにGRCGのモードを書き込んだ後、 I/Oポート7EHから順に、82H,5FH,A4H,D9Hと書き込むと、 フォアグラウンドカラーレジスタの内部での値は、 データ0=8282H, データ1=5F5FH, データ2=A4A4H, ※ここでデータnとは、 データ3=D9D9H プレーンnに対応するデータのことです。 となります。 また、フォアグラウンドカラーレジスタは、モードレジスタ0のビット13あ るいは14のどちらかが1でないと変更できないと書きましたが、GRCGモード でのI/Oポート7EHからのアクセスには適応されません。そうでないと互換性 が維持されなくなってしまいます。 ╌╌╌╌╌╌╌╌╌╌╌╌ § § § NECのEGC、EPSONのEGC § § § ╌╌╌╌╌╌╌╌╌╌╌╌ NECのEGCとEPSONのEGCには若干の違いがあって、EPSONのEGCの方がNECのEGCの上位互換になっています。というよりNECのEGCの欠陥の様な気もしますが。既にあちこちで書いてしまいましたが、 VRAMのリードで、モードレジスタ1のビット10が1の場合、ワンプレー ンリード、コンペアリードともに正常に動作しない。 というのが、それです。正常でない動作も一様書いておくと、 そのリードアクセスの直前にCPUがVRAMに対するライトアクセスをした ときのCPUが書き込んだデータが、読みだされる。 というふうです。EPSONのEGCでは、モードレジスタ1のビット10が1の場合でも正常に、ワンプレーンリード、コンペアリード出来ますが、NECの機械でも動作できるようにしたい場合は、必ず、モードレジスタ1のビット10を0にしてワンプレーンリード、コンペアリードを行って下さい。 ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● このマニュアル作成に当たり、"98スーパテクニック"、"98ゲームグラフィク"、 "PC-9801VXハードウェアマニュアル"、を参考にして、独自に動作確認しま した。 いまだ未完成ですが、一様ネットにアップしてもよいくらいになったと思うので、 アップしました。気づいたことなど有りましたら、ご連絡ください。 東京BBS APPLAUSE